package com.founder.helloworldapp;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.founder.helloworldapp.LocationService.LocationBinder;

import android.location.Location;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.ComponentName;
import android.content.DialogInterface;
import android.content.DialogInterface.OnDismissListener;
import android.content.Intent;
import android.content.ServiceConnection;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleAdapter;

public class MainActivity extends Activity implements OnClickListener, GPSManager.GPSLocationListener {
	
	private Button btnGo;
	
	private ListView trackListView;
	
	private DatabaseHelper dbHelper;
	
	private SimpleAdapter adapter;
	
	private List<Map<String, Object>> trackListData;
	
	private LocationBinder serviceBinder;
	
	private boolean stop;
	
	private long trackId;
	
	private final String TITLE_TEXT = "titleText";
	
	private final String TIME_TEXT = "timeText";
	
	private final String DISTANCE_TEXT = "distanceText";
	
	private final String SPEED_TEXT = "speedText";
	
	private final String TRACK_ID = "trackId";
	
	private final String TRACK = "TRACK";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.track_list);
        dbHelper = new DatabaseHelper(this);
        dbHelper.openDb();
        
        stop = true;
        btnGo = (Button)findViewById(R.id.btn_go);
        btnGo.setText(getString(R.string.button_start));
        btnGo.setOnClickListener(this);
        
        trackListView = (ListView)findViewById(R.id.track_list_view);
        trackListData = new ArrayList<Map<String, Object>>();
        adapter = new SimpleAdapter(this, trackListData, R.layout.track_list_item, 
        		new String[] {TITLE_TEXT, TIME_TEXT, DISTANCE_TEXT, SPEED_TEXT}, 
        		new int[] {R.id.titleText, R.id.timeText, R.id.distanceText, R.id.speedText});
        trackListView.setAdapter(adapter);
        trackListView.setOnItemClickListener(new OnItemClickListener() {
			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
				//Intent intent = new Intent(MainActivity.this, LocationsActivity.class);
				//intent.putExtra("trackId", trackListData.get(position).get("trackId"));
				//MainActivity.this.startActivity(intent);
				Intent intent = new Intent(MainActivity.this, TrackMapActivity.class);
				intent.putExtra("trackId", (Long)trackListData.get(position).get(TRACK_ID));
				MainActivity.this.startActivity(intent);
			}
		});
        
        trackListView.setOnItemLongClickListener(itemLongClickListener);
        
        bindService(new Intent("com.founder.helloworldapp.LocationService"),
               serviceConnection, BIND_AUTO_CREATE);
        loadtracks();
    }

	@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

	@Override
    protected void onDestroy() {
        super.onDestroy();
        dbHelper.closeDb();
        unbindService(serviceConnection);
        if (!stop) {
        	stop = true;
			dbHelper.updateTrackEndDate(trackId);
        }
    }

	private OnItemLongClickListener itemLongClickListener = new OnItemLongClickListener() {
		private Dialog dialog;
		
		private EditText trackName;
		
		private EditText trackInfo;
		
		private int index;
		
		private Map<String, Object> trackData;
		
		private boolean isDelete = false;
		
		private long trackId;
		
		public boolean onItemLongClick(AdapterView<?> parent, View view,
				int position, long id) {
			index = position;
			trackData = trackListData.get(index);
			trackId = (Long)trackData.get(TRACK_ID);
			Log.d("hello", "select trackId="+trackId);
			if (dialog == null) {
				LayoutInflater inflater = getLayoutInflater();
				View layout = inflater.inflate(R.layout.track_edit, null);
				AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this)
				.setTitle(R.string.dialog_title).setView(layout)
				.setPositiveButton(R.string.close_track, null);
				dialog = builder.create();
				
				dialog.setOnDismissListener(new OnDismissListener() {
					public void onDismiss(DialogInterface dialog) {
						if (isDelete) {
							isDelete = !isDelete;
							return;
						}
						Track track = (Track)trackData.get(TRACK);
						//track.setTrackId((Long)trackData.get(TRACK_ID));
						track.setTrackName(trackName.getText().toString());
						track.setInfo(trackInfo.getText().toString());
						dbHelper.updateTrack(track);
						trackData.put(TITLE_TEXT, track.getTrackName() + "(" + formatDate(track.getBeginDate()) + ")");
						adapter.notifyDataSetChanged();
						//Log.d("hello", "index" + index + ",trackId=" + track.getTrackId() + ",trackName" + track.getTrackName() + ",trackInfo" + track.getInfo());
					}
				});
				
				trackName = (EditText)layout.findViewById(R.id.txtTrackName);
				trackInfo = (EditText)layout.findViewById(R.id.txtTrackInfo);
				Button deleteTrack = (Button)layout.findViewById(R.id.btnDeleteTrack);
				deleteTrack.setOnClickListener(new OnClickListener() {
					//long trackId = (Long)trackData.get(TRACK_ID);
					public void onClick(View v) {
						isDelete = true;
						Log.d("hello", "delete trackId="+trackId);
						dbHelper.deleteTrack(trackId);
						trackListData.remove(index);
						adapter.notifyDataSetChanged();
						dialog.dismiss();
					}
				});
			}
			String titleText = (String)trackData.get(TITLE_TEXT);
			int end = titleText.indexOf("(");
			trackName.setText(titleText.substring(0, end));
			Track track = (Track)trackData.get(TRACK);
			trackInfo.setText(track.getInfo());
			dialog.show();
			return true;
		}
    	
    }; 
    
    private String formatTime(long time) {
    	final long sec = 1 * 1000;
    	final long minute = 60 * sec;
    	final long hour = 60 * minute;
    	final long day = 24 * hour;
    	StringBuilder sb = new StringBuilder();
    	if (time <= sec) {
			sb.append("0秒");
			return sb.toString();
    	}
    	while (time > sec) {
    		if (time >= day) {
    			int number = (int)Math.floor(time / day);
    			time = time % day;
    			sb.append(number);
    			sb.append("天");
    			continue;
    		}
    		if (time >= hour) {
    			int number = (int)Math.floor(time / hour);
    			time = time % hour;
    			sb.append(number);
    			sb.append("小时");
    			continue;
    		}
    		if (time >= minute) {
    			int number = (int)Math.floor(time / minute);
    			time = time % minute;
    			sb.append(number);
    			sb.append("分钟");
    			continue;
    		}
			int number = (int)Math.floor(time / sec);
			time = time % sec;
			sb.append(number);
			sb.append("秒");
    	}
    	return "花费" + sb;
    }
    
    private String formatDistance(float distance) {
    	final int km = 1000;
    	StringBuilder sb = new StringBuilder();
		if (distance >= km) {
			sb.append(String.format("%.2f", (distance / km)));
			sb.append("km");
		} else {
			sb.append(String.format("%.1f", distance));
			sb.append("m");
		}
    	return "行程" + sb.toString();
    }
    
    private String formatSpeed(long time, float distance) {
    	final int km = 1000;
    	final long oneminute = 60 * 1000;
    	final long onehour = 60 * oneminute;
    	StringBuilder sb = new StringBuilder();
		if (distance >= km) {
			distance =  distance / km;
			double hour = (double)time / onehour;
			sb.append(String.format("%.2f", (distance / hour)));
			sb.append("km/h");
		} else {
			double minute = (double)time / oneminute;
			sb.append(String.format("%.1f", (distance / minute)));
			sb.append("m/min");
		}
    	return "速度" + sb.toString();
    }
    
    private String formatDate(long date) {
    	SimpleDateFormat df = new SimpleDateFormat("M月d日");
    	return df.format(new Date(date));
    }
    
    private Map<String, Object> initMap(Track track) {
    	Map<String, Object> data = new HashMap<String, Object>();
		data.put(TITLE_TEXT, track.getTrackName() + "(" + formatDate(track.getBeginDate()) + ")");
		long time = track.getEndDate() - track.getBeginDate();
		data.put(TIME_TEXT, formatTime(time));
		data.put(DISTANCE_TEXT, formatDistance(track.getDistance()));
		data.put(SPEED_TEXT, formatSpeed(time, track.getDistance()));
		data.put(TRACK_ID, track.getTrackId());
		data.put(TRACK, track);
		return data;
    }
    
    private void loadtracks() {
    	trackListData.clear();
    	List<Track> tracks = dbHelper.queryTracks();
    	for (Track track : tracks) {
    		trackListData.add(initMap(track));
    	}
    	adapter.notifyDataSetChanged();
    }
    
    private String formatTimeDelay(long time) {
    	final long sec = 1 * 1000;
    	final long minute = 60 * sec;
    	final long hour = 60 * minute;
    	StringBuilder sb = new StringBuilder();
		int number = (int)Math.floor(time / hour);
		time = time % hour;
		sb.append(String.format("%02d", number));
		sb.append(":");
		number = (int)Math.floor(time / minute);
		time = time % minute;
		sb.append(String.format("%02d", number));
		sb.append(":");
		number = (int)Math.floor(time / sec);
		time = time % sec;
		sb.append(String.format("%02d", number));
    	return sb.toString();
    }
    
    private Handler handler = new Handler();  
    
    private Runnable task = new Runnable() {  
  
        public void run() {   
            if (!stop) {  
                handler.postDelayed(this, 1000);
    			long time = System.currentTimeMillis() - trackId;
    			btnGo.setText(getText(R.string.button_stop) + formatTimeDelay(time));
            }  else {
            	btnGo.setText(getString(R.string.button_start));
            }
        }  
    };
    
	public void onClick(View v) {
		stop = !stop;
		if (stop) {
			serviceBinder.stop();
			dbHelper.updateTrackEndDate(trackId);
			loadtracks();
		} else {
			trackId = System.currentTimeMillis();
			Track track = new Track();
			track.setTrackId(trackId);
			track.setTrackName(getString(R.string.my_track));
			track.setBeginDate(trackId);
			track.setEndDate(trackId);
			track.setDistance(0);
			dbHelper.insertTrack(track);
			trackListData.add(0, initMap(track));
			adapter.notifyDataSetChanged();
			serviceBinder.start();
			handler.post(task);
		}
	}
	
	private void updateTrackListItem(float distance, long endDate) {
		Map<String, Object> trackInfo = trackListData.remove(0);
		Track track = (Track)trackInfo.get(TRACK);
		track.setDistance(track.getDistance() + distance);
		track.setEndDate(endDate);
		trackInfo = initMap(track);
		trackListData.add(0, trackInfo);
		adapter.notifyDataSetChanged();
	}

	public void update(Location newLocation, Location oldLocation) {
		if (oldLocation == null) {
			dbHelper.insertLocation(trackId, 0, newLocation);
			return;
		}
		float[] results = new float[1];
		Location.distanceBetween(oldLocation.getLatitude(), oldLocation.getLongitude(), newLocation.getLatitude(), newLocation.getLongitude(), results);
		float distance = results[0];
		updateTrackListItem(distance, newLocation.getTime());
		dbHelper.insertLocation(trackId, distance, newLocation);
	}
	
	private ServiceConnection serviceConnection = new ServiceConnection() {

		public void onServiceConnected(ComponentName name, IBinder service) {
			serviceBinder = (LocationBinder) service;
        	serviceBinder.setListener(MainActivity.this);
		}

		public void onServiceDisconnected(ComponentName name) {
			serviceBinder.setListener(null);
			serviceBinder = null;
		}
    };
}
